/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: EditQuestionPresenter.java
 * Date: 02/03/2011
 */

package com.ingenius.sau.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ingenius.sau.client.AppController;
import com.ingenius.sau.client.Constants;
import com.ingenius.sau.client.event.ListQuestionsEvent;
import com.ingenius.sau.client.service.InstrumentsServiceAsync;
import com.ingenius.sau.client.view.Display;
import com.ingenius.sau.shared.model.instruments.Question;
import com.ingenius.sau.shared.model.instruments.ResponseOption;

/**
 * Class <strong>EditQuestionPresenter</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class EditQuestionPresenter implements EditPresenter {

	public interface EditQuestionDisplay extends Display {

		String getContent();

		void setContent(String content);

		String getQuestionTitle();

		void setQuestionTitle(String title);

		List<ResponseOption> getOptions();

		void setOptions(List<ResponseOption> options);

		String getType();

		void setType(String type);

		void setTypes(List<String> types);

		void show();

		void hide();

	}

	private final HandlerManager eventBus;
	private final InstrumentsServiceAsync rpcService;
	private final EditQuestionDisplay display;
	private Question question;

	public EditQuestionPresenter(HandlerManager eventBus,
			InstrumentsServiceAsync rpcService, EditQuestionDisplay display,
			String questionId) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		loadTypes();
		display.setPresenter(this);

		if (questionId == null) {
			question = new Question();

		} else {
			loadBean(questionId);
		}

	}

	private void loadTypes() {
		List<String> types = new ArrayList<String>();
		types.add(Question.TYPE_OPEN_RESPONSE);
		types.add(Question.TYPE_ONLY_RESPONSE);
		types.add(Question.TYPE_MULTIPLE_RESPONSE);
		display.setTypes(types);
	}

	private void loadBean(String questionId) {
		AppController.setStatusMessage("Loading...");
		rpcService.getQuestion(questionId, new AsyncCallback<Question>() {
			@Override
			public void onSuccess(Question result) {
				if (result == null) {
					onFailure(new Throwable("Database error"));
					return;
				}
				question = result;
				display.setContent(question.getContent());
				display.setQuestionTitle(question.getTitle());
				display.setType(question.getType());
				display.setOptions(question.getResponses());
				hideStatusMessage();
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_GET + Question.class.getName(),
						caught);
				question = new Question();
				// TODO i18n
				String failedMessage = "Failed to retrieve question";
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.client.presenter.EditPresenter#doSaveOrUpdate()
	 */
	@Override
	public void doSaveOrUpdate() {
		question.setContent(display.getContent());
		question.setTitle(display.getQuestionTitle());
		question.setType(display.getType());
		question.setResponses(display.getOptions());

		// TODO i18n
		final String failedMessage = "Failed to save question";
		final String successMessage = "Question saved sucessfully";

		display.hide();
		AppController.setStatusMessage("Saving...");
		rpcService.saveOrUpdateQuestion(question, new AsyncCallback<Boolean>() {
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					eventBus.fireEvent(new ListQuestionsEvent());
					display.showInfo(successMessage);
					hideStatusMessage();

				} else {
					onFailure(new Throwable("Database error"));
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_SAVE
						+ Question.class.getName(), caught);
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.ingenius.sau.client.presenter.Presenter#go(com.google.gwt.user.client
	 * .ui.HasWidgets)
	 */
	@Override
	public void go(HasWidgets container) {
		display.show();
	}

}
